#include <sys_config.h>
#include <types.h>
#include <basic_types.h>
#include <mediatypes.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <osal/osal.h>
#ifndef NEW_DEMO_FRAME
#include <api/libpub29/lib_pub27.h>
#include <api/libpub29/lib_hde.h>
#else
#include <api/libpub/lib_hde.h>
#endif
#include <hld/dis/vpo.h>
#include <api/libosd/osd_lib.h>

//#include <api/libtsi/si_epg.h>
#include <api/libsi/lib_epg.h>

#include "osdobjs_def.h"
#include "string.id"
#include "images.id"
#include "osd_config.h"

#include "menus_root.h"
#include "win_com.h"
#include "win_com_popup.h"
#include "win_com_list.h"

#include "copper_common/com_epg.h"
#include "win_epg.h"
#include "control.h"

#define VACT_EPG_LANG			(VACT_PASS + 4)

/*******************************************************************************
*	Objects definition
*******************************************************************************/
CONTAINER g_win_epg_detail;

BITMAP epg_detail_chan_bmp;
TEXT_FIELD epg_detail_chan;
TEXT_FIELD epg_detail_event_name;
TEXT_FIELD epg_detail_time;
TEXT_FIELD epg_detail_lang;
TEXT_FIELD epg_detail_content;

TEXT_FIELD	epg_detail_split1;

MULTI_TEXT epg_detail_info;
SCROLL_BAR epg_detail_scb;

TEXT_FIELD	epg_detail_split2;

BITMAP epg_detail_help0_bmp;
BITMAP epg_detail_help1_bmp;
TEXT_FIELD epg_detail_help0_txt;
TEXT_FIELD epg_detail_help1_txt;

static VACTION epg_detail_info_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT epg_detail_info_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);;

static VACTION epg_detail_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT epg_detail_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);


#define WIN_SH_IDX	  WSTL_POP_WIN_01_HD


#if Maker_GUI_ON
#define EVENT_SH_IDX WSTL_WIN_TITLE_YJ
#else
#define EVENT_SH_IDX WSTL_TEXT_04_HD
#endif

//#define LANG_SH_IDX WSTL_TEXT_10_HD

#define BAR_SH_IDX  WSTL_SCROLLBAR_01_8BIT//sharon WSTL_SCROLLBAR_01_HD
#define BAR_HL_IDX  WSTL_SCROLLBAR_01_8BIT//sharo WSTL_SCROLLBAR_01_HD

#define BAR_MID_RECT_IDX  	WSTL_NOSHOW_IDX
#define BAR_MID_THUMB_IDX  	WSTL_SCROLLBAR_02_8BIT//sharon WSTL_SCROLLBAR_02_HD

#define BMP_SH_IDX     WSTL_MIX_BMP_HD

#if Maker_GUI_ON
#define SPLIT_LINE_SH	WSTL_WIN_TITLE_YJ
#else
#define SPLIT_LINE_SH	WSTL_WIN_MAINMENU_01_BG_HD
#endif

#ifndef SD_UI
#define	W_L     	250//424
#define	W_T     	120//160
#define	W_W		    550
#define	W_H     	426

#define EVENT_TIMEBMP_L (W_L + 20)
#define EVENT_TIMEBMP_T (W_T + 30)
#define EVENT_TIMEBMP_W 28
#define EVENT_TIMEBMP_H 28

#define CHAN_L (EVENT_TIMEBMP_L+EVENT_TIMEBMP_W)
#define CHAN_T (EVENT_TIMEBMP_T-6)
#define CHAN_W (W_W - 70)
#define CHAN_H 40

#define EVENT_NAME_L (CHAN_L)
#define EVENT_NAME_T (CHAN_T + CHAN_H)
#define EVENT_NAME_W (CHAN_W)
#define EVENT_NAME_H 40

#define EVENT_TIME_L (EVENT_NAME_L)
#define EVENT_TIME_T (EVENT_NAME_T + EVENT_NAME_H)
#define EVENT_TIME_W 320//180//124
#define EVENT_TIME_H 40

#define EVENT_LANG_L (EVENT_TIME_L + EVENT_TIME_W)
#define EVENT_LANG_T (EVENT_TIME_T)
#define EVENT_LANG_W 120//180//134
#define EVENT_LANG_H 40

#define EVENT_CONTENT_L (EVENT_TIME_L)
#define EVENT_CONTENT_T (EVENT_TIME_T + EVENT_TIME_H)
#define EVENT_CONTENT_W 140
#define EVENT_CONTENT_H 40

#define SPLIT_LINE1_L (EVENT_TIMEBMP_L)
#define SPLIT_LINE1_T (EVENT_CONTENT_T + EVENT_CONTENT_H + 4)
#define SPLIT_LINE1_W (EVENT_TIMEBMP_W + CHAN_W)
#define SPLIT_LINE1_H 2

#define DTL_INFO_L  CHAN_L
#define DTL_INFO_T  (SPLIT_LINE1_T + SPLIT_LINE1_H + 4)
#define DTL_INFO_W  400//294
#define DTL_INFO_H  170//156

#define SCB_L (CHAN_L + CHAN_W - 18)
#define SCB_T (DTL_INFO_T)
#define SCB_W 12//18
#define SCB_H (DTL_INFO_H)

#define SPLIT_LINE2_L (SPLIT_LINE1_L)
#define SPLIT_LINE2_T (DTL_INFO_T + DTL_INFO_H + 4)
#define SPLIT_LINE2_W (SPLIT_LINE1_W)
#define SPLIT_LINE2_H 2

#define HELP_BMP_GREEN_L (W_L + 120)
#define HELP_BMP_GREEN_T (DTL_INFO_T + DTL_INFO_H + 10/*16*/)
#define HELP_BMP_GREEN_W 28
#define HELP_BMP_GREEN_H 30

#define HELP_TXT_GREEN_L (HELP_BMP_GREEN_L + HELP_BMP_GREEN_W + 10)
#define HELP_TXT_GREEN_T (HELP_BMP_GREEN_T)
#define HELP_TXT_GREEN_W 130
#define HELP_TXT_GREEN_H 36


#define HELP_BMP_L (W_L + 300)//528)//738
#define HELP_BMP_T (DTL_INFO_T + DTL_INFO_H + 10/*16*/)
#define HELP_BMP_W 28
#define HELP_BMP_H 30

#define HELP_TXT_L (HELP_BMP_L + HELP_BMP_W + 10)
#define HELP_TXT_T (HELP_BMP_T-4)
#define HELP_TXT_W 114
#define HELP_TXT_H 36
#else
#define	W_L     	120//424
#define	W_T     	70//160
#define	W_W		    320
#define	W_H     	320

#define EVENT_TIMEBMP_L (W_L + 10)
#define EVENT_TIMEBMP_T (W_T + 15)
#define EVENT_TIMEBMP_W 24
#define EVENT_TIMEBMP_H 24

#define CHAN_L (EVENT_TIMEBMP_L+EVENT_TIMEBMP_W)
#define CHAN_T (EVENT_TIMEBMP_T)
#define CHAN_W (W_W - 70)
#define CHAN_H 30

#define EVENT_NAME_L (CHAN_L)
#define EVENT_NAME_T (CHAN_T + CHAN_H)
#define EVENT_NAME_W (CHAN_W)
#define EVENT_NAME_H 30

#define EVENT_TIME_L (EVENT_NAME_L)
#define EVENT_TIME_T (EVENT_NAME_T + EVENT_NAME_H)
#define EVENT_TIME_W 240//120//124
#define EVENT_TIME_H 30

#define EVENT_LANG_L (EVENT_TIME_L )
#define EVENT_LANG_T (EVENT_TIME_T + EVENT_TIME_H)
#define EVENT_LANG_W 90//134
#define EVENT_LANG_H 30

#define EVENT_CONTENT_L (EVENT_LANG_L + EVENT_LANG_W)
#define EVENT_CONTENT_T (EVENT_TIME_T + EVENT_TIME_H)
#define EVENT_CONTENT_W 140
#define EVENT_CONTENT_H 30

#define SPLIT_LINE1_L (EVENT_TIMEBMP_L)
#define SPLIT_LINE1_T (EVENT_CONTENT_T + EVENT_CONTENT_H + 4)
#define SPLIT_LINE1_W (EVENT_TIMEBMP_W + CHAN_W)
#define SPLIT_LINE1_H 2

#define DTL_INFO_L  CHAN_L
#define DTL_INFO_T  (SPLIT_LINE1_T + SPLIT_LINE1_H + 4)
#define DTL_INFO_W  220//294
#define DTL_INFO_H  120//156

#define SCB_L (CHAN_L + CHAN_W - 18)
#define SCB_T (DTL_INFO_T)
#define SCB_W 12//18
#define SCB_H (DTL_INFO_H)

#define SPLIT_LINE2_L (SPLIT_LINE1_L)
#define SPLIT_LINE2_T (DTL_INFO_T + DTL_INFO_H + 4)
#define SPLIT_LINE2_W (SPLIT_LINE1_W)
#define SPLIT_LINE2_H 2

#define HELP_BMP_GREEN_L (W_L + 60)
#define HELP_BMP_GREEN_T (DTL_INFO_T + DTL_INFO_H + 10/*16*/)
#define HELP_BMP_GREEN_W 24
#define HELP_BMP_GREEN_H 24

#define HELP_TXT_GREEN_L (HELP_BMP_GREEN_L + HELP_BMP_GREEN_W + 10)
#define HELP_TXT_GREEN_T (HELP_BMP_GREEN_T)
#define HELP_TXT_GREEN_W 90
#define HELP_TXT_GREEN_H 30


#define HELP_BMP_L (W_L + 190)//528)//738
#define HELP_BMP_T (DTL_INFO_T + DTL_INFO_H + 10/*16*/)
#define HELP_BMP_W 24
#define HELP_BMP_H 24

#define HELP_TXT_L (HELP_BMP_L + HELP_BMP_W + 10)
#define HELP_TXT_T (HELP_BMP_T-4)
#define HELP_TXT_W 80
#define HELP_TXT_H 30

#endif

#define LDEF_TXT(root,varTxt,nxtObj,l,t,w,h,sh,align,resID,str)		\
    DEF_TEXTFIELD(varTxt,&root,nxtObj,C_ATTR_ACTIVE,0, \
    0,0,0,0,0, l,t,w,h, sh,sh,sh,sh,   \
    NULL,NULL,  \
    align, 0,0,resID,str)

#define LDEF_BMP(root,varBmp,nxtObj,l,t,w,h,icon)	\
  DEF_BITMAP(varBmp,&root,nxtObj,C_ATTR_ACTIVE,0, \
    0,0,0,0,0, l,t,w,h, BMP_SH_IDX,BMP_SH_IDX,BMP_SH_IDX,BMP_SH_IDX,   \
    NULL,NULL,  \
    C_ALIGN_CENTER | C_ALIGN_VCENTER, 0,0,icon)

#define LDEF_EPG_LINE(parent, varTxt, nxtObj, l, t, w, h, str)		\
    DEF_TEXTFIELD(varTxt,&parent,nxtObj,C_ATTR_ACTIVE,0, \
    0, 0, 0, 0, 0, \
    l, t, w, h,  \
    SPLIT_LINE_SH,SPLIT_LINE_SH,SPLIT_LINE_SH,SPLIT_LINE_SH,   \
    NULL,NULL,  \
    C_ALIGN_CENTER | C_ALIGN_VCENTER, 0,0,0,str)

#define LDEF_MTXT(root,varMtxt,nextObj,ID,l,t,w,h,sh,cnt,sb,content)	\
	DEF_MULTITEXT(varMtxt,&root,nextObj,C_ATTR_ACTIVE,0, \
    	ID,ID,ID,ID,ID, l,t,w,h, sh,sh,sh,sh,   \
	    epg_detail_info_keymap,epg_detail_info_callback,  \
    	C_ALIGN_LEFT | C_ALIGN_TOP, cnt,  4,4,w-8,h-8,sb,content)

#define LDEF_BAR(root,varScb,page,l,t,w,h)	\
	DEF_SCROLLBAR(varScb, &root, NULL, C_ATTR_ACTIVE, 0, \
		0, 0, 0, 0, 0, l, t, w, h, BAR_SH_IDX, BAR_HL_IDX, BAR_SH_IDX, BAR_SH_IDX, \
		NULL, NULL, BAR_VERT_AUTO | SBAR_STYLE_RECT_STYLE, page, BAR_MID_THUMB_IDX, BAR_MID_RECT_IDX, \
		0, 18, w, h - 36, 100, 1)

#define LDEF_WIN(varCon,nxtObj,l,t,w,h,focusID)		\
    DEF_CONTAINER(varCon,NULL,NULL,C_ATTR_ACTIVE,0, \
    0,0,0,0,0, l,t,w,h, WIN_SH_IDX,WIN_SH_IDX,WIN_SH_IDX,WIN_SH_IDX,   \
    epg_detail_keymap,epg_detail_callback,  \
    nxtObj, focusID,0)

extern TEXT_CONTENT detail_mtxt_content[];

LDEF_BMP(g_win_epg_detail,epg_detail_chan_bmp,&epg_detail_chan,\
				EVENT_TIMEBMP_L,EVENT_TIMEBMP_T,EVENT_TIMEBMP_W,EVENT_TIMEBMP_H,IM_ORANGE_ARROW_S)

LDEF_TXT(g_win_epg_detail,epg_detail_chan,&epg_detail_event_name, \
			CHAN_L,CHAN_T,CHAN_W,CHAN_H,EVENT_SH_IDX,C_ALIGN_LEFT | C_ALIGN_VCENTER,0,display_strs[0])

LDEF_TXT(g_win_epg_detail,epg_detail_event_name,&epg_detail_time, \
			EVENT_NAME_L,EVENT_NAME_T,EVENT_NAME_W,EVENT_NAME_H,EVENT_SH_IDX,C_ALIGN_LEFT | C_ALIGN_VCENTER,0,display_strs[1])

LDEF_TXT(g_win_epg_detail,epg_detail_time,&epg_detail_lang, \
			EVENT_TIME_L,EVENT_TIME_T,EVENT_TIME_W,EVENT_TIME_H,EVENT_SH_IDX,C_ALIGN_LEFT | C_ALIGN_VCENTER,0,display_strs[2])

LDEF_TXT(g_win_epg_detail,epg_detail_lang,&epg_detail_content, \
			EVENT_LANG_L,EVENT_LANG_T,EVENT_LANG_W,EVENT_LANG_H,EVENT_SH_IDX,C_ALIGN_RIGHT| C_ALIGN_VCENTER,0,display_strs[3])

LDEF_TXT(g_win_epg_detail,epg_detail_content,&epg_detail_split1, \
			EVENT_CONTENT_L,EVENT_CONTENT_T,EVENT_CONTENT_W,EVENT_CONTENT_H,EVENT_SH_IDX,C_ALIGN_LEFT | C_ALIGN_VCENTER,0,display_strs[4])

LDEF_EPG_LINE(g_win_epg_detail, epg_detail_split1, &epg_detail_info, SPLIT_LINE1_L, SPLIT_LINE1_T, SPLIT_LINE1_W, SPLIT_LINE1_H, NULL);

LDEF_BAR(epg_detail_info,epg_detail_scb,6,SCB_L,SCB_T, SCB_W, SCB_H)

LDEF_MTXT(g_win_epg_detail,epg_detail_info,&epg_detail_split2,1, \
			DTL_INFO_L,DTL_INFO_T,DTL_INFO_W,DTL_INFO_H,EVENT_SH_IDX,1,&epg_detail_scb,detail_mtxt_content)

LDEF_EPG_LINE(g_win_epg_detail, epg_detail_split2, &epg_detail_help0_bmp, SPLIT_LINE2_L, SPLIT_LINE2_T, SPLIT_LINE2_W, SPLIT_LINE2_H, NULL);

LDEF_BMP(g_win_epg_detail,epg_detail_help0_bmp,&epg_detail_help0_txt,\
				HELP_BMP_GREEN_L,HELP_BMP_GREEN_T,HELP_BMP_GREEN_W,HELP_BMP_GREEN_H,IM_EPG_COLORBUTTON_GREEN)
LDEF_TXT(g_win_epg_detail,epg_detail_help0_txt,&epg_detail_help1_bmp, \
				HELP_TXT_GREEN_L,HELP_BMP_GREEN_T,HELP_TXT_GREEN_W,HELP_BMP_GREEN_H,EVENT_SH_IDX,C_ALIGN_LEFT | C_ALIGN_VCENTER,RS_SYSTEM_LANGUAGE,NULL)				

LDEF_BMP(g_win_epg_detail,epg_detail_help1_bmp,&epg_detail_help1_txt,\
				HELP_BMP_L,HELP_BMP_T,HELP_BMP_W,HELP_BMP_H,IM_EPG_COLORBUTTON_RED)
LDEF_TXT(g_win_epg_detail,epg_detail_help1_txt,NULL, \
				HELP_TXT_L,HELP_BMP_T,HELP_TXT_W,HELP_BMP_H,EVENT_SH_IDX,C_ALIGN_LEFT | C_ALIGN_VCENTER,RS_COMMON_CANCEL,NULL)				

LDEF_WIN(g_win_epg_detail,&epg_detail_chan_bmp,W_L, W_T, W_W, W_H,1)

/*******************************************************************************
*	Local functions & variables declare
*******************************************************************************/
TEXT_CONTENT detail_mtxt_content[] =
{
	{STRING_UNICODE,0},
};

#define	DETAIL_BUFFER_LEN		1024*3

UINT16 *detail_str = NULL;
UINT16 current_channel;
struct winepginfo* current_event_info;

/*******************************************************************************
*	Local functions definition
*******************************************************************************/
static INT32 win_epg_detail_info_update(eit_event_info_t *ep,INT32 idx)
{
	INT32 strlen=0, len;
	UINT8 *p_short=NULL;
	UINT8 *p_extend=NULL;
	UINT16 *p=detail_str;
	INT32 short_num,extented_num,i;
	UINT8* s;

	s = epg_get_event_language(ep);
	if(s!=NULL)
	{
		if(MEMCMP(s,"ara",3)==0)
			detail_mtxt_content[0].bTextType = STRING_REVERSE;
		else
			detail_mtxt_content[0].bTextType = STRING_UNICODE;
	}

	if(detail_mtxt_content[0].bTextType == STRING_REVERSE)
	{
		len = epg_get_event_all_extented_detail(ep, p, DETAIL_BUFFER_LEN);
		if(len!=0)
		{
			p[len++] = 0x2a00;	//'*'
			p[len] = 0;
			if(len < DETAIL_BUFFER_LEN-1)
			{
				p[len++] = 0x0a00;	//"\n"
				p[len] = 0;
			}
		}

		strlen = epg_get_event_all_short_detail(ep, p+len, DETAIL_BUFFER_LEN-len);
		if(strlen!=0)
		{
			len += strlen;
			p[len++] = 0x2a00;	//'*'
			p[len] = 0;
		}

		api_str_reverse(p,len);
	}
	else
	{
		len = epg_get_event_all_short_detail(ep,p+1,DETAIL_BUFFER_LEN-1);
		if(len!=0)
		{
			p[0] = 0x2a00;	//'*'
			len++;
			if(len < DETAIL_BUFFER_LEN-1)
			{
				p[len++] = 0x0a00;	//"\n"
				p[len] = 0;
			}
		}

		strlen = epg_get_event_all_extented_detail(ep,p+len+1,DETAIL_BUFFER_LEN-len-1);
		if(strlen!=0)
		{
			p[len] = 0x2a00;	//'*'
			len += strlen+1;
		}
	}
	epg_detail_info.nLine = 0;
		
	if(p!=NULL && len > 0)
	{
		OSD_SetAttr((POBJECT_HEAD)&epg_detail_scb, C_ATTR_ACTIVE);
	}
	else
	{
		OSD_SetAttr((POBJECT_HEAD)&epg_detail_scb, C_ATTR_HIDDEN);
	}
		
	detail_mtxt_content[0].text.pString = detail_str;

	return len;

}

static void win_epg_detail_display(UINT16 channel, struct winepginfo*epginfo)
{
	P_NODE service_info;
//	T_NODE tp_info;
	PTEXT_FIELD chan,name,lang,time,content;
	PMULTI_TEXT info;
	eit_event_info_t* ep = NULL;
	INT32 event_num;
	UINT16 unistr[30];
	INT8 str[30],str2[30];
	INT32 len;
	UINT16 event_name[33];
	UINT8* s;
	UINT16 num = 0;	//event index
	UINT8 lang_tatol = 0;
	UINT8 lang_select = 0;

	chan = &epg_detail_chan;
	name = &epg_detail_event_name;
	time = &epg_detail_time;
	lang = &epg_detail_lang;
	content = &epg_detail_content;
	info = &epg_detail_info;

	/*channel*/
	if(get_prog_at(channel, &service_info) != SUCCESS)
		goto NO_VALID_EVENT;

	if(service_info.ca_mode)
		sprintf(str,"%04d $",channel + 1);
	else
		sprintf(str,"%04d ",channel + 1);

	ComAscStr2Uni(str,unistr);
	len = ComUniStrLen(unistr);

	ComUniStrCopyChar((UINT8*)&unistr[len], service_info.service_name);			
	OSD_SetTextFieldContent(chan, STRING_UNICODE, (UINT32)unistr);
	
	if(epginfo->event_idx == INVALID_ID)
	{
		goto NO_VALID_EVENT;
	}

	ep = epg_get_cur_service_event(channel, SCHEDULE_EVENT, &epginfo->start, &epginfo->end, &event_num, FALSE);
/*	if(NULL == ep)
	{
		ep=epg_get_cur_service_event(channel, PRESENT_EVENT, &epginfo->start, &epginfo->end, &event_num, FALSE);	
		if (ep == NULL)
			ep=epg_get_cur_service_event(channel, FOLLOWING_EVENT, &epginfo->start, &epginfo->end, &event_num, FALSE);	
	}*/

	while(ep!=NULL)
	{
		if(ep->event_id==epginfo->event_idx)
		{	
			s = epg_get_event_name(ep,&len);
			if (s == NULL)
			{
				goto NO_VALID_EVENT;
			}

			OSD_SetTextFieldContent(name,STRING_UNICODE,(UINT32)s);

			epg_get_event_start_time(ep,str);
			len = STRLEN(str);

			STRCPY(&str[len],"~");
			len = STRLEN(str);

			epg_get_event_end_time(ep,str2);

			STRCPY(&str[len],str2);

			OSD_SetTextFieldContent(time, STRING_ANSI, (UINT32)str);

			s = (UINT8*)epg_get_event_language(ep);
			if (s == NULL)
			{
				goto NO_VALID_EVENT;
			}

			lang_tatol = epg_get_event_language_count(ep);
			lang_select = epg_get_event_language_select(ep);
			if ( lang_tatol == 0 )
				sprintf(str, "%s(%d/%d)", s, 0, lang_tatol);
			else
				sprintf(str, "%s(%d/%d)", s, lang_select+1, lang_tatol);

			OSD_SetTextFieldContent(lang,STRING_ANSI,(UINT32)str);

			epg_get_event_content_type(ep,str,&len);

			OSD_SetTextFieldContent(content, STRING_ANSI, (UINT32)str);

			len = win_epg_detail_info_update(ep,0);
		
			break;
		}
//		ep=ep->next;
		ep = epg_get_schedule_event(++num);
	}

	if(ep==NULL)
	{
NO_VALID_EVENT:
		STRCPY(str,"");
		OSD_SetTextFieldContent(name, STRING_ANSI, (UINT32)str);
		OSD_SetTextFieldContent(time, STRING_ANSI, (UINT32)str);
		OSD_SetTextFieldContent(lang, STRING_ANSI, (UINT32)str);
		OSD_SetTextFieldContent(content, STRING_ANSI, (UINT32)str);

		OSD_SetAttr((POBJECT_HEAD)&epg_detail_scb, C_ATTR_HIDDEN);
		detail_mtxt_content[0].text.pString = NULL;
	}
}


static void win_epg_detail_refresh()
{
	PTEXT_FIELD chan,name,lang,content;
	PMULTI_TEXT info;
	
	/* refresh item */
	chan = &epg_detail_chan;
	name = &epg_detail_event_name;
	lang = &epg_detail_lang;
	content = &epg_detail_content;
	info = &epg_detail_info;
	
	OSD_TrackObject((POBJECT_HEAD)chan, C_UPDATE_ALL);
	OSD_TrackObject((POBJECT_HEAD)name, C_UPDATE_ALL);
	OSD_TrackObject((POBJECT_HEAD)lang, C_UPDATE_ALL);
	OSD_TrackObject((POBJECT_HEAD)content, C_UPDATE_ALL);
	OSD_TrackObject((POBJECT_HEAD)info, C_UPDATE_ALL);
}

/*
 * win_epg_detail_lang_change - switch language and redraw detail window
 */
static void win_epg_detail_lang_change()
{
	UINT8 lang_select;
	UINT8 count;
	INT32 event_num;
	eit_event_info_t *ep;
	
	ep = epg_get_cur_service_event(current_channel, SCHEDULE_EVENT, 
				&current_event_info->start, &current_event_info->end, &event_num, FALSE);

	count = epg_get_event_language_count(ep);
	lang_select = epg_get_event_language_select(ep);

	if (count <= 1)
		return;
	
	lang_select = (lang_select + 1) % count;
	epg_set_event_langcode_select(ep->lang[lang_select].lang_code2);
	
	win_epg_detail_display(current_channel, current_event_info);

	win_epg_detail_refresh();

}



/*******************************************************************************
*	key mapping and event callback definition
*******************************************************************************/
static VACTION epg_detail_info_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act = VACT_PASS;

	switch(key)
	{
		case V_KEY_UP:
			act = VACT_CURSOR_UP;
			break;
		case V_KEY_DOWN:
			act = VACT_CURSOR_DOWN;
			break;
		case V_KEY_P_UP:
			act = VACT_CURSOR_PGUP;
			break;
		case V_KEY_P_DOWN:
			act = VACT_CURSOR_PGDN;
			break;
		default:
			act = VACT_PASS;
	}

	return act;	

}

static PRESULT epg_detail_info_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;

	return ret;
}

static PRESULT epg_detail_unkown_act_proc(VACTION act)
{
	PRESULT ret = PROC_PASS;
	
	switch(act) {
		case VACT_EPG_LANG:
			win_epg_detail_lang_change();
			break;
		default:
			break;
	}

	return ret;
}


static VACTION epg_detail_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act = VACT_PASS;

	switch(key)
	{
		case V_KEY_EXIT:
			act = VACT_CLOSE;
			break;
		case V_KEY_MENU:
			act = VACT_CLOSE;
			break;
		case V_KEY_RED:
			act = VACT_CLOSE;
			break;
		case V_KEY_GREEN:
			act = VACT_EPG_LANG;
			break;
		default:
			act = VACT_PASS;
	}

	return act;	

}

static PRESULT epg_detail_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
	UINT16 channel;
	VACTION unact;
	
	switch(event)
	{
		case EVN_PRE_OPEN:
			break;
		case EVN_POST_OPEN:
			break;
		case EVN_PRE_CLOSE:			
			/* Make OSD not flickering */
			*((UINT32*)param2) &= ~C_CLOSE_CLRBACK_FLG; 
			break;
		case EVN_POST_CLOSE:
			if (detail_str)
			{
				FREE(detail_str);		
				detail_str=NULL;
			}	
			break;
		case EVN_UNKNOWN_ACTION:
			unact = (VACTION)(param1>>16);
			ret = epg_detail_unkown_act_proc(unact);
			break;
	}

	return ret;
}

void win_epg_detail_open(UINT16 channel, struct winepginfo* epginfo)
{
	POBJECT_HEAD pObj = (POBJECT_HEAD)&g_win_epg_detail;
	PRESULT bResult = PROC_LOOP;
	UINT32 hkey;

	if (detail_str==NULL)
		detail_str=MALLOC(DETAIL_BUFFER_LEN*sizeof(UINT16));

	if(detail_str == NULL)
		return;
	
	MEMSET(detail_str,0,DETAIL_BUFFER_LEN*sizeof(UINT16));

	current_channel = channel;
	current_event_info = epginfo;
	
	wincom_backup_region(&g_win_epg_detail.head.frame);

	win_epg_detail_display(channel,epginfo);

	OSD_ObjOpen(pObj, MENU_OPEN_TYPE_OTHER);

	BOOL old_value = ap_enable_key_task_get_key(TRUE);	
	while(bResult != PROC_LEAVE)
	{

		hkey = ap_get_key_msg();
	    if(hkey == INVALID_HK || hkey == INVALID_MSG)
	    {
	        continue;
	    }
		
		bResult = OSD_ObjProc(pObj, (MSG_TYPE_KEY<<16),hkey, 0);		
	}
	ap_enable_key_task_get_key(old_value);
	
	if (detail_str)
	{
		FREE(detail_str);		
		detail_str=NULL;
	}	
	wincom_restore_region();
}
